﻿#region Using References

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

#endregion

namespace Beaker.Services.FileSystem
{
	[ContractClass( typeof( FileSystemServiceContracts ) )]
	public interface IFileSystemService
		: IFolder
	{
		/// <summary>
		/// Parse the given path and return a file or folder for it
		/// </summary>
		/// <param name="path">The path to parse</param>
		/// <returns>A IFileSystemEntry with the file or folder, or <c>null</c> when the file or folder does not exist</returns>
		/// <exception cref="FormatException">Thrown when the path could not be parsed.</exception>
		IFileSystemEntry ParsePath( string path );

		/// <summary>
		/// Gets the requested special folder
		/// </summary>
		/// <param name="folder">The special folder to get</param>
		/// <returns>The requested special folder</returns>
		IFolder GetSpecialFolder( Environment.SpecialFolder folder );
	}

	[ContractClassFor( typeof( IFileSystemService ) )]
	public abstract class FileSystemServiceContracts
		: IFileSystemService
	{
		#region Implementation of IFolder

		/// <summary>
		/// Gets the files in this folder.
		/// </summary>
		/// <returns>
		/// A sequence of files.
		/// </returns>
		public IEnumerable<IFile> GetFiles()
		{
			//Contract.Ensures( Contract.Result<IEnumerable<IFile>>() != null );
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the file with the given name.
		/// </summary>
		/// <param name="fileName">The name of the file to get.</param>
		/// <returns>The file with the given name, or <c>null</c> when it could not be found.</returns>
		public IFile GetFile( string fileName )
		{
			// result can be null
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the folders in this folder.
		/// </summary>
		/// <returns>
		/// A sequence of folders.
		/// </returns>
		public IEnumerable<IFolder> GetFolders()
		{
			//Contract.Ensures( Contract.Result<IEnumerable<IFolder>>() != null );
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the folder with the given name.
		/// </summary>
		/// <param name="folderName">The name of the folder to get.</param>
		/// <returns>The folder with the given name, or <c>null</c> when it could not be found.</returns>
		public IFolder GetFolder( string folderName )
		{
			// result can be null
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the entires in this folder.
		/// </summary>
		/// <returns>
		/// A sequence of items.
		/// </returns>
		public IEnumerable<IFileSystemEntry> GetEntries()
		{
			//Contract.Ensures( Contract.Result<IEnumerable<IFileSystemEntry>>() != null );
			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the entry with the given name in this folder.
		/// </summary>
		/// <param name="entryName">Name of the entry to get.</param>
		/// <returns>The entry with the given name, or <c>null</c> when it could not be found.</returns>
		public IFileSystemEntry GetEntry( string entryName )
		{
			// result can be null
			throw new NotImplementedException();
		}

		#endregion
		#region Implementation of IFileSystemEntry

		/// <summary>
		/// Gets the name of the entry
		/// </summary>
		string IFileSystemEntry.Name
		{
			get { throw new NotImplementedException(); }
		}

		/// <summary>
		/// Get the folder this entry is in
		/// </summary>
		IFolder IFileSystemEntry.ParentFolder
		{
			get { throw new NotImplementedException(); }
		}

		#endregion

		/// <summary>
		/// Parse the given path and return a file or folder for it
		/// </summary>
		/// <param name="path">The path to parse</param>
		/// <returns>A IFileSystemEntry with the file or folder, or <c>null</c> when the file or folder does not exist</returns>
		/// <exception cref="FormatException">Thrown when the path could not be parsed.</exception>
		public IFileSystemEntry ParsePath( string path )
		{
			Contract.Requires<ArgumentNullException>( !string.IsNullOrEmpty( path ) );
			// result can be null (file or folder does not exist)
			// can throw when intput path is invalid

			throw new NotImplementedException();
		}

		/// <summary>
		/// Gets the requested special folder
		/// </summary>
		/// <param name="folder">The special folder to get</param>
		/// <returns>The requested special folder</returns>
		public IFolder GetSpecialFolder( Environment.SpecialFolder folder )
		{
			Contract.Requires<ArgumentOutOfRangeException>( Enum.IsDefined( typeof( Environment.SpecialFolder ), folder ) );
			// result can be null
			throw new NotImplementedException();
		}

	}
}
